/*
 * PDLogger
 * 
 * Copyright (c) 2012, Zoujie Wu <yibn2008@gmail.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 * 
 *   * Redistributions of source code must retain the above copyright notice, this 
 *     list of conditions and the following disclaimer.
 *   
 *   * Redistributions in binary form must reproduce the above copyright notice, 
 *     this list of conditions and the following disclaimer in the documentation 
 *     and/or other materials provided with the distribution.
 *   
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/* $Id$ */

#ifndef PDL_OVERRIDE_H
#define PDL_OVERRIDE_H

#define PDL_O_FN(name)					ZEND_FN(pdl_o_##name)
#define PDL_O_MN(class, name)			ZEND_MN(pdl_o_##class##_##name)
#define PDL_O_FUNCTION(name)			ZEND_NAMED_FUNCTION(PDL_O_FN(name))
#define PDL_O_METHOD(class, name)		ZEND_NAMED_FUNCTION(PDL_O_MN(class, name))

#define PDL_MN_KEY(class, name)			#class "::" #name

#define PDL_GET_O_METHOD(class, name, ofunc) \
	pdl_get_override_func(&PDL_G(override_funcs), PDL_MN_KEY(class, name), sizeof(PDL_MN_KEY(class, name)) - 1, &ofunc TSRMLS_CC)
#define PDL_GET_O_FUNCTION(name, ofunc) \
	pdl_get_override_func(&PDL_G(override_funcs), #name, sizeof(#name) - 1, &ofunc TSRMLS_CC)

#define PDL_ADD_O_METHOD(ht, class, name) pdl_add_override_func(ht, #class, sizeof(#class)-1, #name, sizeof(#name)-1, PDL_O_MN(class, name) TSRMLS_CC)
#define PDL_ADD_O_FUNCTION(ht, name) pdl_add_override_func(ht, NULL, 0, #name, sizeof(#name)-1, PDL_O_FN(name) TSRMLS_CC)

#define PDL_OE(override)		{NULL, override, NULL, }
#define PDL_OE_END				{NULL, NULL, NULL, NULL}

typedef void (*php_func)(INTERNAL_FUNCTION_PARAMETERS);

typedef struct _pdl_override_func_t {
	php_func			origin;			/* original function handler */
	php_func			override;		/* override function handler */
	zend_function		*func;			/* the function to override */
	zend_class_entry	*ce;			/* the class entry of override function */
} pdl_override_func_t;

/* define override internal APIs */
PDL_API int pdl_add_override_func(HashTable *ht, char *class_name, int class_len, char *func_name, int func_len, php_func override TSRMLS_DC);
PDL_API void pdl_replace_override_funcs(int override TSRMLS_DC);
PDL_API int pdl_get_override_func(HashTable *ht, char *key, uint key_len, pdl_override_func_t **ofunc TSRMLS_DC);

/* override internal functions */
PDL_O_METHOD(PDO, __construct);
PDL_O_METHOD(PDO, prepare);
PDL_O_METHOD(PDO, query);
PDL_O_METHOD(PDO, exec);
PDL_O_METHOD(PDO, beginTransaction);
PDL_O_METHOD(PDO, rollBack);
PDL_O_METHOD(PDO, commit);

#endif	/* PDL_OVERRIDE_H */
/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
